
/*
 * Created on Jun 18, 2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */

/**
 * @author david-1
 */

package com.herohead;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;

import org.apache.log4j.Logger;

/**
 * This is used for MOFT sequences
 */

public class Sequence {

	static Logger logger = Logger.getLogger(Sequence.class);

	int seqVal = 0;
	String seqFile;
	String path;
	String seqPrefix = "";
	String padString = "0";
	char pad = padString.charAt(0);
	int padsize;

	/**
	 * 
	 * @param p_path - sequence path
	 * @param p_seqPrefix - sequence prefix
	 * @param p_seqSize - sequence aka padsize
	 */

	//	############################################################################
	public Sequence (String p_path, String p_seqPrefix, int p_seqSize) {
		//	############################################################################
		setPrefix(p_seqPrefix);
		path = p_path;
		padsize = p_seqSize;
	}

	/**
	 * Checks and compares the sequence file against the data passed
	 * @param string to compare
	 * @return true sequence check is good
	 *         false sequence check is bad
	 */
	//	############################################################################
	public boolean checkSeq(String retreived) {
		//	############################################################################

		increase();

		if (getSeqFormatted().compareTo(retreived) == 0) {
			decrease();
			return true;
		} else {
			decrease();
			return false;
		}
	}
	//	############################################################################
	public void checkSeqerror(String retreived) {
		//	############################################################################

		increase();

		int currentSeq;
		String seqFiletemp;
		int seqValTemp;
		currentSeq = getSeq();

		seqFiletemp = retreived.substring(seqPrefix.length(),retreived.length());
		seqValTemp = Integer.parseInt(seqFiletemp);

		if (seqValTemp > currentSeq) {
			decrease();
			setSeq(seqValTemp);
			logger.warn("Resetting sequence to " + getSeqFormatted());


		} else {
			decrease();
			logger.warn("Leaving sequence at " + getSeqFormatted());
		}

	}

	/**
	 * Decreases the sequence by one. If the sequence is 1 it will
	 * reset to 99999
	 *
	 */

	//	############################################################################
	public void decrease() {
		//	############################################################################
		if (seqVal == 0) {
			setSeq(99999);
		}
		seqVal--;
		logger.debug("Decreasing Sequence to " + getSeq());
	}
	/**
	 * returnes the raw sequence number (not formated)
	 * @return sequence number in raw format
	 * 
	 */
	//	############################################################################
	public String getPrefix() {
		//	############################################################################

		return seqPrefix;
	}
	/**
	 * Returns the current sequence
	 * 
	 * @return current sequence
	 * 
	 */

	//	############################################################################
	public int getSeq() {
		//	############################################################################
		return seqVal;
	}
	/**
	 * Returns the current sequence file
	 * @return current sequence file
	 * 
	 */
	//	############################################################################
	public String getSeqFile() {
		//	############################################################################

		return seqFile;
	}

	/**
	 * Returns the sequence in the correct format (includes Prefix)
	 * 
	 * @return sequence formated as the file
	 * 
	 */
	//	############################################################################
	public String getSeqFormatted() {
		//	############################################################################
		return seqPrefix + paddingString(String.valueOf(getSeq()),padsize,pad,true);
	}
	/**
	 * Increases the sequence by one. If the sequence is 99999 it
	 * will reset the number to 1
	 *
	 */
	//	############################################################################
	public void increase() {
		//	############################################################################

		if (seqVal == 99999) {

			setSeq(0);
		}
		seqVal++;
		logger.debug("Increasing Sequence to " + getSeq());
	}
	/**
	 * pads the sequence out with the parameters passed
	 * @param sequence number
	 *        pad size
	 *        pading char
	 *        pad left (true) or right (false)
	 * @return the padded sequence number
	 * 
	 */
	//	############################################################################
	public String paddingString( String s, int n, char c , boolean paddingLeft  ) {
		//	############################################################################
		StringBuffer str = new StringBuffer(s);
		int strLength  = str.length();
		if ( n > 0 && n > strLength ) {
			for ( int i = 0; i <= n ; i ++ ) {
				if ( paddingLeft ) {
					if ( i < n - strLength ) str.insert( 0, c );
				}
				else {
					if ( i > strLength ) str.append( c );
				}
			}
		}
		return str.toString();
	}

	/**
	 * reads the sequence file and returns it
	 * @return the sequence number in raw format
	 */
	//	############################################################################
	public int readSeq() {
		//	############################################################################

		final String fle = seqPrefix;
		String seqString;

		FilenameFilter filter = new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				return name.startsWith(fle);
			}
		};

		File seqDir = new File(path);
		String[] lst = seqDir.list(filter);
		String[] reviseLst = new String[100];

		int aCnt = 0;

		for (int i = 0; i < lst.length; i++) {
			if (lst[i].length() == (padsize + fle.length())) {
				reviseLst[aCnt] = lst[i];
				aCnt++;
			}
		}

		System.out.println(aCnt);


		String[] reviseLst1 = new String[aCnt];

		System.arraycopy(reviseLst,0,reviseLst1,0,aCnt);

		lst = reviseLst1;

		if (lst.length == 0) {
			try {
				File file = new File(path + seqPrefix + paddingString("",padsize,pad,true));
				// Create file if it does not exist
				boolean success = file.createNewFile();
				if (success) {
					// File did not exist and was created
				} else {
					// File already exists
				}
			} catch (IOException e) {
			}
			seqFile = seqPrefix + paddingString("",padsize,pad,true);
			//logger.debug("here is the seqFile " + seqFile);

		} else {
			if (lst.length > 1) {
				Arrays.sort(lst);
				seqFile = lst[lst.length - 1];
				logger.warn("Multiple sequences found with the same name. Using largest sequence file found " + seqFile);
			} else {
				seqFile = lst[0];
			}
		}

		seqString = seqFile.substring(seqPrefix.length(),seqFile.length());
		seqVal = Integer.parseInt(seqString);
		return seqVal;
	}
	/**
	 * Sets the prefix
	 * @param prefix as a string
	 * 
	 */
	//	############################################################################
	public void setPrefix(String prefix) {
		//	############################################################################

		seqPrefix = prefix;
	}

	/**
	 * Set sequence
	 * @param seq sequence number to be set
	 */

	//	############################################################################
	public void setSeq(int seq) {
		//	############################################################################

		seqVal = seq;
	}
	/**
	 * Writes out the sequence file
	 * @return the sequence file that was written out
	 */
	//	############################################################################
	public String writeSeq() {
		//	############################################################################

		String sCurrent = new String(path + seqFile);
		File current = new File(sCurrent);
		String sNewFile = new String(path + seqPrefix + paddingString(String.valueOf(seqVal),padsize,pad,true));
		File newfile = new File(sNewFile);

		boolean success = current.renameTo(newfile);

		if (!success) {
			logger.error(sCurrent + " can't be renamed to " + sNewFile);
		} else {
			logger.info(sCurrent + " renamed to " + sNewFile);
		}


		seqFile = seqPrefix + paddingString(String.valueOf(seqVal),padsize,pad,true);

		return seqFile;
	}
}

